package com.tl.satoken.netty;

import com.tl.satoken.domain.entity.Player;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class ChannelGroupManager {
    
    private final Map<String, ChannelGroup> roomChannelGroups = new ConcurrentHashMap<>();
    private final Map<String, Player> channelPlayerMap = new ConcurrentHashMap<>();
    private final Map<String, String> playerRoomMap = new ConcurrentHashMap<>();
    
    public void addPlayerToRoom(String roomId, Player player, Channel channel) {
        ChannelGroup channelGroup = roomChannelGroups.computeIfAbsent(roomId, 
            k -> new DefaultChannelGroup(GlobalEventExecutor.INSTANCE));
        
        channelGroup.add(channel);
        channelPlayerMap.put(channel.id().asShortText(), player);
        playerRoomMap.put(player.getId(), roomId);
        
        log.info("玩家 {} 加入房间 {}, 当前房间人数: {}", player.getUsername(), roomId, channelGroup.size());
    }
    
    public void removePlayerFromRoom(String playerId, Channel channel) {
        String roomId = playerRoomMap.remove(playerId);
        if (roomId != null) {
            ChannelGroup channelGroup = roomChannelGroups.get(roomId);
            if (channelGroup != null) {
                channelGroup.remove(channel);
                log.info("玩家 {} 离开房间 {}, 剩余人数: {}", playerId, roomId, channelGroup.size());
                
                if (channelGroup.isEmpty()) {
                    roomChannelGroups.remove(roomId);
                    log.info("房间 {} 已清空，删除房间", roomId);
                }
            }
        }
        
        channelPlayerMap.remove(channel.id().asShortText());
    }
    
    public ChannelGroup getRoomChannelGroup(String roomId) {
        return roomChannelGroups.get(roomId);
    }
    
    public Player getPlayerByChannel(String channelId) {
        return channelPlayerMap.get(channelId);
    }
    
    public String getPlayerRoomId(String playerId) {
        return playerRoomMap.get(playerId);
    }
    
    public int getRoomPlayerCount(String roomId) {
        ChannelGroup channelGroup = roomChannelGroups.get(roomId);
        return channelGroup != null ? channelGroup.size() : 0;
    }
    
    public void broadcastToRoom(String roomId, Object message) {
        ChannelGroup channelGroup = roomChannelGroups.get(roomId);
        if (channelGroup != null) {
            channelGroup.writeAndFlush(message);
        }
    }
    
    public void broadcastToRoomExcept(String roomId, Object message, Channel excludeChannel) {
        ChannelGroup channelGroup = roomChannelGroups.get(roomId);
        if (channelGroup != null) {
            int broadcastCount = 0;
            for (Channel channel : channelGroup) {
                if (!channel.equals(excludeChannel)) {
                    channel.writeAndFlush(message);
                    broadcastCount++;
                }
            }
            log.info("广播消息到房间 {}: 排除了发送者，向 {} 个连接发送了消息", roomId, broadcastCount);
        } else {
            log.warn("房间 {} 不存在，无法广播消息", roomId);
        }
    }
    
    public void removeChannel(Channel channel) {
        String channelId = channel.id().asShortText();
        Player player = channelPlayerMap.get(channelId);
        if (player != null) {
            removePlayerFromRoom(player.getId(), channel);
        }
    }
    
    public int getTotalRooms() {
        return roomChannelGroups.size();
    }
    
    public int getTotalPlayers() {
        return channelPlayerMap.size();
    }
}
